import json
import os
import requests
import re
import datetime
from typing import List, Dict, Any, Optional, Union

from config.FileHandle import MCP_TOOLS_PATH

# GitHub API基础URL
GITHUB_API_BASE = 'https://api.github.com'


def read_mcp_tools() -> Dict[str, Any]:
    """读取MCP工具配置文件"""
    try:
        if os.path.exists(MCP_TOOLS_PATH):
            with open(MCP_TOOLS_PATH, 'r', encoding='utf-8') as f:
                return json.load(f)
        else:
            # 如果文件不存在，创建一个空的配置
            default_config = {"projects": []}
            with open(MCP_TOOLS_PATH, 'w', encoding='utf-8') as f:
                json.dump(default_config, f, ensure_ascii=False, indent=2)
            return default_config
    except json.JSONDecodeError:
        # 如果JSON解析失败，返回空配置
        return {"projects": []}
    except Exception as e:
        print(f"读取MCP工具配置失败: {str(e)}")
        return {"projects": []}


def write_mcp_tools(data: Dict[str, Any]) -> None:
    """写入MCP工具配置文件"""
    try:
        with open(MCP_TOOLS_PATH, 'w', encoding='utf-8') as f:
            json.dump(data, f, ensure_ascii=False, indent=2)
    except Exception as e:
        print(f"写入MCP工具配置失败: {str(e)}")


def get_all_projects() -> List[Dict[str, Any]]:
    """获取所有MCP项目，包括本地配置"""
    config = read_mcp_tools()
    raw_projects = config.get("projects", [])
    standardized: List[Dict[str, Any]] = []
    
    for proj in raw_projects:
        try:
            # 统一 githubUrl 字段
            github_url = proj.get("githubUrl") or proj.get("url") or ""
            proj["githubUrl"] = github_url
            proj.pop("url", None)
            
            # 确保 id 为字符串类型
            proj["id"] = str(proj.get("id", ""))
            
            # 确保有command字段
            if not proj.get("command"):
                if "server_script" in proj:
                    # 根据脚本类型设置命令
                    server_script = proj.get("server_script", "")
                    if server_script.endswith(".py"):
                        proj["command"] = "python"
                    elif server_script.endswith(".js"):
                        proj["command"] = "node"
                    else:
                        proj["command"] = "uvicorn"
                    
                    # 设置args
                    if not proj.get("args"):
                        proj["args"] = [server_script]
                else:
                    # 默认命令
                    proj["command"] = "uvicorn"
                    proj["args"] = []
            
            standardized.append(proj)
        except Exception as e:
            print(f"标准化项目失败: {str(e)}")
    
    return standardized


def contains_agent_keywords(text: str) -> bool:
    """检查文本中是否包含AI代理或MCP相关关键词"""
    if not text:
        return False
    
    keywords = [
        'ai agent', 'ai-agent', 'aiagent',
        'llm agent', 'llm-agent',
        'autonomous agent', 'autonomous-agent',
        'agent framework', 'agent-framework',
        'multi-agent', 'multiagent',
        'agent orchestration', 'agent-orchestration',
        'mcpTool', 'multi-agent collaboration protocol',
        'agent communication',  'mcp'
    ]
    
    text_lower = text.lower()
    return any(keyword in text_lower for keyword in keywords)


def parse_github_url(url: str) -> Optional[Dict[str, str]]:
    """从GitHub URL提取仓库名和所有者"""
    if not url:
        return None
    
    try:
        # 匹配GitHub URL格式
        match = re.search(r'github\.com\/([^\/]+)\/([^\/]+)', url)
        if match and len(match.groups()) >= 2:
            return {
                "owner": match.group(1),
                "repo": match.group(2).replace('.git', '').split('?')[0].split('#')[0]  # 移除.git后缀和URL参数
            }
        return None
    except Exception as e:
        print(f"解析GitHub URL出错: {e}")
        return None


def search_repositories(query: str, token: str = None) -> List[Dict[str, Any]]:
    """搜索GitHub仓库，返回仓库信息字典列表"""
    if not query:
        return []
    
    # 构建搜索URL
    encoded_query = requests.utils.quote(query)
    per_page = 100
    search_url = f"{GITHUB_API_BASE}/search/repositories?q={encoded_query}&sort=stars&order=desc&per_page={per_page}"
    
    # 设置请求头
    headers = {'Accept': 'application/vnd.github.v3+json'}
    if token:
        headers['Authorization'] = f'Bearer {token}'
    
    try:
        # 发送请求
        response = requests.get(search_url, headers=headers, timeout=10)
        response.raise_for_status()  # 如果请求失败，抛出异常
        
        data = response.json()
        
        repositories = []
        # 处理搜索结果，过滤关键字后收集仓库信息
        for item in data.get('items', []):
            if contains_agent_keywords(item.get('name', '')) or contains_agent_keywords(item.get('description', '')):
                repo = {
                    'id': str(item.get('id')),
                    'name': item.get('name'),
                    'description': item.get('description'),
                    'githubUrl': item.get('html_url'),
                    'stars': item.get('stargazers_count', 0),
                    'lastUpdated': item.get('updated_at', '').split('T')[0],
                    'language': item.get('language'),
                    'owner': item.get('owner', {}).get('login', 'unknown'),
                    'tags': ['agent', 'mcpTool', 'imported']
                }
                repositories.append(repo)
        return repositories
    except requests.RequestException as e:
        print(f"GitHub API请求失败: {e}")
        return []
    except Exception as e:
        print(f"搜索GitHub仓库出错: {e}")
        return []


def add_project(project: Dict[str, Any]) -> Dict[str, Any]:
    """添加新项目"""
    # 获取现有项目
    config = read_mcp_tools()
    projects = config.get("projects", [])
    
    # 检查URL是否已存在
    if any(p.get('githubUrl') == project.get('githubUrl') for p in projects):
        raise ValueError("项目URL已存在")
    
    # 解析GitHub URL获取所有者
    parsed = parse_github_url(project.get('githubUrl'))
    owner = parsed.get('owner') if parsed else 'unknown'
    
    # 创建新项目
    current_date = datetime.datetime.now().strftime("%Y-%m-%d")
    new_project = {
        **project,
        "id": str(len(projects) + 1),
        "stars": project.get("stars", 0),
        "lastUpdated": project.get("lastUpdated", current_date),
        "owner": owner,
        "command": project.get("command", "python"),
        "args": project.get("args", [])
    }
    
    # 添加到项目列表
    projects.append(new_project)
    config["projects"] = projects
    
    # 保存到配置文件
    write_mcp_tools(config)
    
    return new_project


def add_projects(projects_data: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
    """批量添加项目对象列表"""
    if not projects_data:
        return []
        
    # 获取现有项目
    config = read_mcp_tools()
    projects = config.get("projects", [])
    existing_urls = {p.get('githubUrl') for p in projects}
    new_projects: List[Dict[str, Any]] = []
    current_date = datetime.datetime.now().strftime("%Y-%m-%d")
    
    # 添加来自前端的每个项目对象
    for proj in projects_data:
        github_url = proj.get('githubUrl')
        if not github_url or github_url in existing_urls:
            continue
            
        # 解析 owner
        parsed = parse_github_url(github_url)
        owner = proj.get('owner') or (parsed.get('owner') if parsed else 'unknown')
        
        # 生成 id
        new_id = str(len(projects) + len(new_projects) + 1)
        
        # 确保有命令和参数
        command = proj.get("command")
        args = proj.get("args", [])
        if not command:
            server_script = proj.get("server_script", "")
            if server_script.endswith(".py"):
                command = "python"
                args = [server_script]
            elif server_script.endswith(".js"):
                command = "node"
                args = [server_script]
            else:
                command = "uvicorn"
        
        new_proj = {
            **proj,
            'id': new_id,
            'owner': owner,
            'lastUpdated': proj.get('lastUpdated') or current_date,
            'command': command,
            'args': args
        }
        
        projects.append(new_proj)
        new_projects.append(new_proj)
        existing_urls.add(github_url)
        
    # 保存更新
    config['projects'] = projects
    write_mcp_tools(config)
    return new_projects


def get_project_by_id(project_id: str) -> Optional[Dict[str, Any]]:
    """按ID获取项目"""
    projects = get_all_projects()
    for project in projects:
        if project.get('id') == project_id:
            return project
    return None


def refresh_agent_data() -> List[Dict[str, Any]]:
    """刷新代理数据"""
    return get_all_projects()


def delete_project(project_id: str) -> List[Dict[str, Any]]:
    """根据项目ID删除项目并返回更新后的列表"""
    config = read_mcp_tools()
    projects = config.get("projects", [])
    # 过滤掉匹配ID的项目
    updated = [p for p in projects if str(p.get('id')) != project_id]
    config["projects"] = updated
    write_mcp_tools(config)
    return get_all_projects()